/*
 * @Author: jiu yin
 * @Date: 2025-01-02 17:51:02
 * @FilePath: \node_udp\src\webSocket\dll\index.js
 * @LastEditTime: 2025-01-03 11:14:53
 * @LastEditors: jiu yin zhen jing
 */

//企业文档 https://bytedance.larkoffice.com/docx/doxcnxkcC2Si6GgIGplpkAZNHjh
//参考文档 https://koffi.dev/variables
//参考文档 https://docs.ffffee.com/electron/electron-koffi/koffi-%E5%AE%98%E6%96%B9%E4%BE%8B%E5%AD%90.html
let path = require("path");

const koffi = require("koffi");
const filePath = path.join(__dirname, "./PXREAClientSDK.dll");
const pxreaDll = koffi.load(filePath);
// const lib2 = pxreaDll;
// 定义回调函数类型

// 初始化设备连接
// @param {void*} - 设备参数
// @param {void*} - 配置参数
// @param {unsigned int} - 配置标志
// @returns {int} - 返回状态码，0表示成功
const Init = pxreaDll.func("int Init(void*, void*, unsigned int)");

// 获取设备电池电量
// @param {void*} - 设备标识
// @returns {int} - 返回电池电量百分比或错误码
const GetBattery = pxreaDll.func("int GetBattery(void*)");

// 获取当前运行的应用信息
// @param {void*} - 设备标识
// @returns {int} - 返回当前应用状态码
const GetCurrentApp = pxreaDll.func("int GetCurrentApp(void*)");

// 锁定设备屏幕
// @param {void*} - 设备标识
// @returns {int} - 返回操作状态码，0表示成功
const LockDevice = pxreaDll.func("int LockDevice(void*)");

// 解锁设备屏幕
// @param {void*} - 设备标识
// @returns {int} - 返回操作状态码，0表示成功
const UnlockDevice = pxreaDll.func("int UnlockDevice(void*)");

// 启动应用程序
// @param {void*} - 设备标识
// @param {void*} - 应用程序参数
// @returns {int} - 返回操作状态码，0表示成功
const StartPlayApp = pxreaDll.func("int StartPlayApp(void*, void*)");

// 停止应用程序
// @param {void*} - 设备标识
// @returns {int} - 返回操作状态码，0表示成功
const StopPlayApp = pxreaDll.func("int StopPlayApp(void*)");

// 开始监控设备
// @param {void*} - 设备标识
// @returns {int} - 返回操作状态码，0表示成功
const StartMonitor = pxreaDll.func("int StartMonitor(void*)");

// 停止监控设备
// @param {void*} - 设备标识
// @returns {int} - 返回操作状态码，0表示成功
const StopMonitor = pxreaDll.func("int StopMonitor(void*)");

// 获取屏幕状态
// @param {const char*} devID - 设备ID字符串
// @returns {int} - 返回屏幕状态码
const GetScreenState = pxreaDll.func("int GetScreenState(const char *devID)");

// 设置屏幕状态
// @param {void*} - 设备标识
// @param {unsigned int} - 屏幕状态标志
// @returns {int} - 返回操作状态码，0表示成功
const SetScreenState = pxreaDll.func("int SetScreenState(void*,unsigned int)");

// 关闭设备
// @param {void*} - 设备标识
// @returns {int} - 返回操作状态码，0表示成功
const ShutDownDevice = pxreaDll.func("int ShutDownDevice(void*)");

// 重启设备
// @param {void*} - 设备标识
// @returns {int} - 返回操作状态码，0表示成功
const RestartDevice = pxreaDll.func("int RestartDevice(void*)");

// const lib1 = koffi.load("src/assets/dll/testAddDll.dll");
// const nativeSum = lib1.func("__stdcall", "add", "int", ["int", "int"]);
// let result = nativeSum(1, 2);
// console.log(result);

const PXREAOpenApiCallbackType = {
	PXREAFrameCaptureStart: 1,
	PXREAFrameCaptureStop: 1 << 1,
	/// @brief 服务已连接
	PXREAServerConnect: 1 << 2,
	/// @brief 服务已断开
	PXREAServerDisconnect: 1 << 3,
	/// @brief 设备上线
	PXREADeviceFind: 1 << 4,
	/// @brief 设备离线
	PXREADeviceMissing: 1 << 5,
	/// @brief 设备电量
	PXREADeviceBattery: 1 << 6,
	/// @brief 设备已锁定
	PXREADeviceLock: 1 << 7,
	/// @brief 设备已解锁
	PXREADeviceUnlock: 1 << 8,
	/// @brief 设备连接
	PXREADeviceConnect: 1 << 9,
	/// @brief 设备佩戴传感器
	PXREADeviceSensor: 1 << 10,
	/// @brief 设备关闭
	PXREADeviceShutdown: 1 << 11,
	/// @brief 设备唤醒
	PXREADeviceResume: 1 << 12,
	/// @brief 画面监控参数返回
	/// @deprecated 已废弃 被具体的流类型取代
	PXREADeviceMonitorParameter: 1 << 13,
	/// @brief 监控画面帧
	/// @deprecated 已废弃 被具体的流类型取代
	PXREADeviceMonitor: 1 << 14,
	/// @brief 设备型号
	PXREADeviceModel: 1 << 15,
	/// @brief 设备当前应用程序
	PXREACurrentApplication: 1 << 16,
	/// @brief 手柄电量
	PXREAControllerBattery: 1 << 17,
	/// @brief 当前屏幕状态
	PXREAScreenState: 1 << 18,
	/// @brief 播控指令执行结果
	PXREAVideoControlResult: 1 << 19,
	/// @brief 屏幕监控参数返回
	PXREADeviceScreenMonitorParameter: 1 << 20,
	/// @brief 屏幕监控画面帧
	PXREADeviceScreenMonitor: 1 << 21,
	/// @brief 自定义流监控参数返回
	PXREADeviceStreamMonitorParameter: 1 << 22,
	/// @brief 自定义流监控画面帧
	PXREADeviceStreamMonitor: 1 << 23,
	/// @brief 设备别名
	PXREADeviceAlias: 1 << 24,
	/// @brief 设备状态Json描述
	PXREADeviceStateJson: 1 << 25,
	/// @brief 自定义消息
	PXREADeviceCustomMessage: 1 << 26,
	/// @brief 掩码,用于开启全部回调
	PXREAFullMask: 0xffffffff,
};

//定义回调类型
const SDKCallBack = koffi.proto("void SDKCallBack(int context, int type, int status, const void *userData )");
// const SDKCallBack = koffi.proto("void SDKCallBack(int context, int type, int status, int userData )");
const CallbackPtr = koffi.pointer(SDKCallBack);
//注册回调

// 定义结构体
let devData = koffi.pack("DevData", {
	devID: koffi.array("char", 32),
});
let devDataBattery = koffi.pack("DevDataBattery", {
	devID: koffi.array("char", 32),
	battery: "int8_t",
});

const TYPES = PXREAOpenApiCallbackType;
const asyncCallback = koffi.register((context, type, status, userDataPtr) => {
	let userData;
	// console.log(userDataPtr);
	userData = koffi.decode(userDataPtr, devData);
	// console.log(`Callback received:context=${context} type=${type} status=${status}, devID=`, userData.devID);
  switch (type) {
    case TYPES.PXREAFrameCaptureStart:
        console.log("帧捕获开始");
        break;
    case TYPES.PXREAFrameCaptureStop:
        console.log("帧捕获停止");
        break;
    case TYPES.PXREAServerConnect:
        console.log("行为: 服务器连接成功");
        break;
    case TYPES.PXREAServerDisconnect:
        console.log("行为: 服务器断开连接");
        break;
    case TYPES.PXREADeviceFind:
        console.log(`行为: 设备发现`, userData);
        break;
    case TYPES.PXREADeviceMissing:
        console.log("行为: 设备离线");
        break;
    case TYPES.PXREADeviceBattery:
        userData = koffi.decode(userDataPtr, devDataBattery);
        console.log("电量获取", userData.battery, "设备ID", userData.devID.toString());
        break;
    case TYPES.PXREADeviceLock:
        console.log("行为: 设备已锁定");
        break;
    case TYPES.PXREADeviceUnlock:
        console.log("行为: 设备已解锁");
        break;
    case TYPES.PXREADeviceConnect:
        console.log(`行为: 设备连接成功 ${userData}`);
        break;
    case TYPES.PXREADeviceSensor:
        console.log("行为: 设备佩戴传感器状态变化");
        break;
    case TYPES.PXREADeviceShutdown:
        console.log("行为: 设备关闭");
        break;
    case TYPES.PXREADeviceResume:
        console.log("行为: 设备唤醒");
        break;
    case TYPES.PXREADeviceMonitorParameter:
        console.log("行为: 画面监控参数返回 (已废弃)");
        break;
    case TYPES.PXREADeviceMonitor:
        console.log("行为: 监控画面帧 (已废弃)");
        break;
    case TYPES.PXREADeviceModel:
        console.log("行为: 设备型号信息");
        break;
    case TYPES.PXREACurrentApplication:
        console.log("行为: 当前应用程序状态");
        break;
    case TYPES.PXREAControllerBattery:
        console.log("行为: 手柄电量状态");
        break;
    case TYPES.PXREAScreenState:
        console.log("设备屏幕状态", status);
        break;
    case TYPES.PXREAVideoControlResult:
        console.log("行为: 播控指令执行结果");
        break;
    case TYPES.PXREADeviceScreenMonitorParameter:
        console.log("行为: 屏幕监控参数返回");
        break;
    case TYPES.PXREADeviceScreenMonitor:
        console.log("行为: 屏幕监控画面帧");
        break;
    case TYPES.PXREADeviceStreamMonitorParameter:
        console.log("行为: 自定义流监控参数返回");
        break;
    case TYPES.PXREADeviceStreamMonitor:
        console.log("行为: 自定义流监控画面帧");
        break;
    case TYPES.PXREADeviceAlias:
        console.log("行为: 设备别名更新");
        break;
    case TYPES.PXREADeviceStateJson:
        console.log(`行为: 设备JSON数据获取成功 ${userData}`);
        break;
    case TYPES.PXREADeviceCustomMessage:
        console.log("行为: 收到自定义消息");
        break;
    default:
        console.log("未知的回调类型:", type);
}
}, CallbackPtr);

//调用 Init 函数
const context = 123; //场景id
Init(context, asyncCallback, PXREAOpenApiCallbackType.PXREAFullMask);
const devID = "PA7N10MGG8071802W";
// 定期调用获取电池状态
setInterval(async () => {
	await GetBattery(devID);
	await LockDevice(devID);
	await SetScreenState(devID, 0);
	// await RestartDevice(devID);
	// await GetScreenState(devID);
	// await RestartDevice(devID);
	// console.log("电量结果:", batteryResult);
}, 5000); // 每5秒调用一次

// 保持程序运行
console.log("程序正在运行，按 Ctrl+C 退出。");
// 在程序结束时注销回调
process.on("exit", () => {
	koffi.unregister(asyncCallback);
});
